/**
 * 
 */
package graph;


/**
 * @author xiaohui
 * 
 */
public class MBR {

	/**
	 * The minimum coordinates.
	 */
	private double[] coord;
	/**
	 * The extensions.
	 */
	private double[] ext;

	private final int X = 0;
	private final int Y = 1;
	private final int WIDTH = 0;
	private final int HEIGHT = 1;
	private final int DIM = 2;

	public MBR(double minX, double minY, double width, double height) {
		coord = new double[2];
		coord[0] = minX;
		coord[1] = minY;

		ext = new double[2];

		ext[WIDTH] = width;
		ext[HEIGHT] = height;
	}

	public boolean contains(MBR mbr) {
		if ((mbr == null) || (mbr.numOfDimensions() != DIM))
			return false;
		return contains(mbr.getMinCoords()) && contains(mbr.getMaxCoords());
	}

	public boolean contains(double[] point) {
		return contains(point, 0);
	}

	private int numOfDimensions() {

		return DIM;
	}

	public boolean contains(double[] point, int tolerance) {
		if ((point == null) || (point.length < DIM))
			throw new IllegalArgumentException("wrong argument");
		for (int i = 0; i < DIM; i++)
			if (point[i] + tolerance < coord[i])
				return false;
			else if (point[i] - tolerance > coord[i] + ext[i])
				return false;
		return true;
	}

	/**
	 * Determines whether this MBR and the specified MBR intersect.
	 * Two MBRs intersect if their intersection is nonempty.  
	 * @return  true if the specified MBR and this MBR intersect; false otherwise
	 * @param  r  the other MBR
	 */
	public boolean intersects(MBR r) {
		return intersects(r,0);
	}
	/**
	 * Determines whether this MBR and the specified MBR intersect with a given tolerance.
	 * Two MBRs intersect if their intersection is nonempty.  
	 * @return  true if the specified MBR and this MBR intersect; false otherwise
	 * @param  r  the other MBR
	 * @param  tolerance  the tolerance
	 */
	public boolean intersects (MBR r, int tolerance) {
		if ((r == null) || (r.numOfDimensions() != DIM))
			return false;
		for (int i=0; i<DIM; i++) {
			if (coord[i] + ext[i] + tolerance <= r.coord[i])
				return false;
			if (coord[i] - tolerance >= r.coord[i] + r.ext[i])
				return false;
		}
		return true;
	}
	/**
	 * Returns the maximum coordinates.
	 * 
	 * @return the maximum coordinates
	 */
	public double[] getMaxCoords() {
		double[] res = new double[DIM];
		for (int i = 0; i < DIM; i++)
			res[i] = coord[i] + ext[i];
		return res;
	}

	/**
	 * Returns the minimum coordinates.
	 * 
	 * @return the minimum coordinates
	 */
	public double[] getMinCoords() {
		return coord;
	}

}
